// // ******************************************************************
// //       /\ /|       @file       MediaQueryHandler.cs
// //       \ V/        @brief      await29
// //       | "")       @author     Await, 285283010@qq.com
// //       /  |
// //      /  \\        @Modified   2025-01-02 20:01
// //    *(__\_\        @Copyright  Copyright (c) , 2024-12-27 18:12 Await
// // ******************************************************************

using System.Linq.Expressions;
using AutomaticSubtitles.Contracts.Dto;
using AutomaticSubtitles.Service.Application.Media.Queries;
using AutomaticSubtitles.Service.DataAccess.Model;
using AutomaticSubtitles.Service.Domain.Media;
using AutomaticSubtitles.Service.Domain.Translate;

namespace AutomaticSubtitles.Service.Application.Media;

/// <summary>
/// 媒体查询处理器
/// </summary>
public class MediaQueryHandler(IMediaRepository repository, ISubtitleRepository subtitleRepository) : BaseAutoService
{
    /// <summary>
    /// 获取所有媒体列表
    /// </summary>
    [EventHandler]
    public async Task Handler(GetMediaListQuery query)
    {
        var options = new PaginatedOptions
        {
            Page = query.PageIndex,
            PageSize = query.PageSize,
            Sorting = new Dictionary<string, bool> { { query.SortField ?? "id", query.SortOrder } }
        };

        Expression<Func<Auto_Media, bool>>? predicate = x => x.MediaType == (GlobalVariableEnumConfiguration.MediaEnum)query.MediaType && x.Leve == 0;
        if (!string.IsNullOrWhiteSpace(query.Name)) predicate = predicate.And(x => x.Name.Contains(query.Name));

        var result = await repository.GetPaginatedListAsync(predicate, options);
        var mapToList = result.Result.MapToList<MediaDto>();
        //获取每个视频下面有哪些字幕
        if (mapToList != null)
        {
            foreach (var mediaDto in mapToList)
            {
                var subtitleList = await subtitleRepository.GetListAsync(x => x.VideoId == mediaDto.Id);
                mediaDto.Subtitle = subtitleList.Select(x => x.Language).Distinct().ToList();
            }

            foreach (var mediaDto in mapToList)
                mediaDto.Nfo = mediaDto.MediaType == (int)GlobalVariableEnumConfiguration.MediaEnum.电影
                    ? VideoFileUtils.NfoMoveInformationOfTheMedia(mediaDto.InformationAddress)?.MapTo<NfoDto>()
                    : VideoFileUtils.NfoTvInformationOfTheMedia(mediaDto.InformationAddress)?.MapTo<NfoDto>();
            query.Result = new PaginatedResponseDto<MediaDto>
            {
                Total = result.Total,
                TotalPages = result.TotalPages,
                Result = mapToList
            };
        }
    }

    /// <summary>
    /// 根据ID获取媒体
    /// </summary>
    [EventHandler]
    public async Task Handler(GetMediaByIdQuery query)
    {
        var media = await repository.FindAsync(query.id);
        query.Result = media.MapTo<MediaDto>();
    }

    /// <summary>
    ///     基于id查询获取媒体图像数据
    /// </summary>
    [EventHandler]
    public async Task Handler(GetMediaImageDataBasedPathQuery query)
    {
        IsDataNotExist(query.path);
        //判断文件是否存在media.PosterAddress
        if (File.Exists(query.path)) query.Result = File.OpenRead(query.path);
    }


    /// <summary>
    ///     获取媒体收藏列表查询
    /// </summary>
    [EventHandler]
    public async Task Handler(GetMediaCollectionListQuery query)
    {
        var media = await repository.FindAsync(query.Id);
        IsDataNotExist(media);
        var autoMediae = await repository.GetListAsync(x => x.ParentLevelId == media!.Id);
        var mapToList = autoMediae.MapToList<MediaDto>();
        List<MediaCollectionDto>? data = null;
        var subtitleList = (await subtitleRepository.GetListAsync(x => autoMediae.Select(s => s.Id).Contains(x.VideoId))).ToList();
        if (mapToList != null)
            foreach (var mediaDtose in mapToList.GroupBy(x => x.Quarter))
            {
                var collectInformation = mediaDtose.ToList();
                foreach (var mediaDto in collectInformation) mediaDto.Subtitle = subtitleList.Where(x => x.VideoId == mediaDto.Id).Select(x => x.Language).Distinct().ToList();
                collectInformation.OrderBy(x => x.Name).ToList().ForEach(x => x.Nfo = VideoFileUtils.NfoTvInformationOfTheMedia(x.InformationAddress)?.MapTo<NfoDto>());
                var mediaCollectionDto = new MediaCollectionDto()
                {
                    Season = mediaDtose.Key,
                    Nfo = VideoFileUtils.NfoTvInformationOfTheMedia(media!.InformationAddress)?.MapTo<NfoDto>(),
                    Data = collectInformation
                };
                data ??= [];
                data.Add(mediaCollectionDto);
            }

        if (data != null)
        {
            data = data.OrderBy(x => x.Season).ToList();
            query.Result = data;
        }
    }

    [EventHandler]
    public async Task Handler(GetMediaRandomDataQuery query)
    {
        var media = await repository.GetMediaRandomData();
        query.Result = media;
    }
}